#define KEYCODE_BACKSPACE 127

#include <iostream>
#include <termios.h>

using namespace std;

string input(int len, const string &hint = "", bool no_clear = false,
             const string &judge = "");

bool judge(const string &input, const string &answer);

string judge_str(const string &input, const string &answer);

const auto NONE = string::npos;
const string COLOR_DEFAULT = "\033[39m";
const string COLOR_RED = "\033[31m";
const string COLOR_GREEN = "\033[32m";
const string COLOR_YELLOW = "\033[33m";
const string tip = COLOR_RED + "红色=位置错误+字母错误" + COLOR_YELLOW
        + ";黄色=位置错误+字母正确" + COLOR_GREEN + ";绿色=完全正确\n"
        + COLOR_DEFAULT;

int main() {
    string key;
    string judge_s;
    cout << COLOR_DEFAULT + "玩法说明：当前版本中，字母个数为 6 个，不得重复，共 6 次机会" << endl;
    input(1, "请按任意字母继续...", true);
    // 读取谜底
    while (true) {
        key = input(6, "请输入谜底：");
        if (input(1, "谜底是：" + key + "确定吗(y/n)") == "y") {
            break;
        }
    }
    // 猜词
    for (int i = 0; i < 6; ++i) {
        auto guess = input(6, tip + "请猜词：", false,
                           judge_s);
        judge_s = judge_str(guess, key) + "\n";
        if (judge(guess, key)) {
            cout << COLOR_GREEN + "恭喜你猜对了！" << endl;
            input(1, "请按任意字母退出...", true);
            return 0;
        } else {
            judge_s += COLOR_RED + "回答错误" + "还剩" + char('0' + 6 - i - 1)
                       + "次机会\n";
        }
    }
    input(1, "请按任意字母退出...", false,
          judge_s.append(COLOR_RED));
    cout << "挑战失败！" << endl;
    return 0;
}

char getch() {
    struct termios tm{}, tm_old{};
    int fd = 0, ch;

    if (tcgetattr(fd, &tm) < 0) {//保存现在的终端设置
        return -1;
    }

    tm_old = tm;
    cfmakeraw(&tm);//更改终端设置为原始模式，该模式下所有的输入数据以字节为单位被处理
    if (tcsetattr(fd, TCSANOW, &tm) < 0) {//设置上更改之后的设置
        return -1;
    }

    ch = getchar();
    if (tcsetattr(fd, TCSANOW, &tm_old) < 0) {//更改设置为最初的样子
        return -1;
    }

    return char(ch);
}

string input(int len, const string &hint, bool no_clear,
             const string &judge) {
    string s;
    auto bad_character = false, repeated = false;
    while (s.size() < len) {
        if (!no_clear) {
            system("clear");
        }
        cout << judge << COLOR_DEFAULT + hint;
        cout << s;
        for (int i = 0; i < len - s.size(); ++i) {
            cout << "_";
        }
        if (bad_character) {
            cout << endl << COLOR_RED + "[!]输入的字符必须在 a～z 之间";
            bad_character = false;
        }
        if (repeated) {
            cout << endl << COLOR_RED + "[!]输入字符不得重复";
            repeated = false;
        }
        auto ch = getch();
        if (ch >= 'a' && ch <= 'z' && s.find(ch) == NONE) {
            s += ch;
        } else if (ch == KEYCODE_BACKSPACE) {
            // Delete the last one
            s.pop_back();
        } else if (s.find(ch) != NONE) {
            repeated = true;
        } else {
            bad_character = true;
        }
    }
    if (!no_clear) {
        system("clear");
    }
    return s;
}

bool judge(const string &input, const string &answer) {
    string s;
    auto flag = true;
    for (int i = 0; i < input.size(); ++i) {
        if (input[i] == answer[i]) {
            s += COLOR_GREEN + input[i];
        } else {
            s += input[i];
            flag = false;
        }
    }
    system("clear");
    cout << s + COLOR_DEFAULT << endl;
    return flag;
}

string judge_str(const string &input, const string &answer) {
    string s;
    for (int i = 0; i < input.size(); ++i) {
        if (input[i] == answer[i]) {
            s += COLOR_GREEN + input[i];
        } else if (answer.find(input[i]) != NONE) {
            s += COLOR_YELLOW + input[i];
        } else {
            s += COLOR_RED + input[i];
        }
    }
    system("clear");
    cout << s + COLOR_DEFAULT << endl;
    return s;
}
